package yi.wuhenbot.Service;

import com.alibaba.fastjson2.JSON;
import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import yi.wuhenbot.Controller.BotController;
import yi.wuhenbot.Utils.QQBotUtil;
import yi.wuhenbot.entity.Payload;

/**
 * 机器人请求处理类
 * 统一处理私聊、群聊、频道、频道私信四种类型的消息
 * 对外保留原有四个入口方法，内部统一逻辑
 * @author wuhen
 */
@Service
public class BotRequest {
    private static final Logger logger = LoggerFactory.getLogger(BotController.class);

    @Autowired
    private QQBotUtil qqBotUtil;

    @Autowired
    private ContentJudgmentService contentJudgmentService;

    /**
     * 用户私聊消息-测试返回监听到的内容
     * 对外接口，供 BotController 调用
     */
    public void handlePrivateMessageTest(String rawBody) {
        // 调用统一处理逻辑，指定消息类型为私聊
        handleMessage(rawBody, MessageType.PRIVATE);
    }

    /**
     * 用户群聊消息-测试返回监听到的内容
     * 对外接口，供 BotController 调用
     */
    public void handleGroupMessageTest(String rawBody) {
        // 调用统一处理逻辑，指定消息类型为群聊
        handleMessage(rawBody, MessageType.GROUP);
    }

    /**
     * 用户频道消息-测试返回监听到的内容
     * 对外接口，供 BotController 调用
     */
    public void handleChannelMessageTest(String rawBody) {
        // 调用统一处理逻辑，指定消息类型为频道
        handleMessage(rawBody, MessageType.CHANNEL);
    }

    /**
     * 用户频道私信消息-测试返回监听到的内容
     * 对外接口，供 BotController 调用
     */
    public void handleDirectMessageTest(String rawBody) {
        // 调用统一处理逻辑，指定消息类型为频道私信
        handleMessage(rawBody, MessageType.DIRECT);
    }

    /**
     * 统一消息处理核心逻辑
     * 根据消息类型提取对应参数，并调用内容判断服务
     * @param rawBody 原始消息体
     * @param messageType 消息类型枚举
     */
    private void handleMessage(String rawBody, MessageType messageType) {
        try {
            // 1. 解析原始消息体，获取Payload中的D对象（包含完整消息数据）
            JSONObject jsonObject = new JSONObject(JSON.parseObject(rawBody, Payload.class).getD().toString());

            // 2. 提取消息内容ID，用于后续回复时引用（防止重复响应）
            String contentId = jsonObject.getString("id");

            // 3. 根据消息类型提取用户OpenID（不同消息类型存储在不同字段）
            String userOpenid = extractUserOpenid(jsonObject, messageType);
            logger.info("提取用户ID：{}", userOpenid);

            // 4. 根据消息类型提取typeID（私聊为用户ID，群聊为群ID，频道为频道ID）
            String typeID = extractTypeId(jsonObject, messageType);
            // 5. 将消息类型枚举转换为String类型（Group/Private/Channel/Direct）
            String type = messageType.name();

            logger.info("消息类型：{}", type);
            logger.info("类型ID：{}", typeID);

            // 6. 检查消息是否包含内容字段
            if (jsonObject.has("content")) {
                // 7. 提取消息内容并去除首尾空格
                String content = jsonObject.getString("content").trim();
                logger.info("收到消息内容：{}", content);

                // 8. 处理频道消息中的@机器人标记（移除<@!12345>格式）
                if (messageType == MessageType.CHANNEL) {
                    content = content.replaceAll("<@![0-9]+>", "").strip();
                }

                // 9. 调用内容判断服务处理消息，传入typeID和type参数
                String response = contentJudgmentService.contentJudgment(content, userOpenid, typeID, type);

                // 10. 根据消息类型调用对应的发送方法返回响应
                sendResponseByType(messageType, typeID, userOpenid, response, contentId);

            } else {
                // 11. 记录无内容字段的消息日志
                String completeMessage = jsonObject.toString();
                logger.info("消息无content字段，完整内容：{}", completeMessage);
            }
        } catch (Exception e) {
            // 12. 捕获并记录消息处理过程中的任何异常
            logger.error("消息处理失败，消息类型：{}", messageType, e);
        }
    }

    /**
     * 根据消息类型提取用户OpenID
     * 不同消息类型存储用户ID的字段不同
     * @param jsonObject 消息JSON对象
     * @param messageType 消息类型枚举
     * @return 用户OpenID
     */
    private String extractUserOpenid(JSONObject jsonObject, MessageType messageType) {
        switch (messageType) {
            case PRIVATE:
                // 私聊消息：user_openid字段
                return jsonObject.getJSONObject("author").getString("user_openid");
            case GROUP:
                // 群聊消息：member_openid字段
                return jsonObject.getJSONObject("author").getString("member_openid");
            case CHANNEL:
                // 频道消息：union_openid字段
                return jsonObject.getJSONObject("author").getString("union_openid");
            case DIRECT:
                // 频道私信：union_openid字段
                return jsonObject.getJSONObject("author").getString("union_openid");
            default:
                // 未知消息类型抛出异常
                throw new IllegalArgumentException("不支持的消息类型: " + messageType);
        }
    }

    /**
     * 根据消息类型提取typeID
     * 私聊返回用户ID，群聊返回群ID，频道返回频道ID
     * @param jsonObject 消息JSON对象
     * @param messageType 消息类型枚举
     * @return 类型ID
     */
    private String extractTypeId(JSONObject jsonObject, MessageType messageType) {
        switch (messageType) {
            case PRIVATE:
                // 私聊的typeID为用户OpenID
                return jsonObject.getJSONObject("author").getString("user_openid");
            case GROUP:
                // 群聊的typeID为群OpenID
                return jsonObject.getString("group_openid");
            case CHANNEL:
                // 频道的typeID为频道ID
                return jsonObject.getString("channel_id");
            case DIRECT:
                // 频道私信的typeID为频道服务器ID
                return jsonObject.getString("guild_id");
            default:
                throw new IllegalArgumentException("不支持的消息类型: " + messageType);
        }
    }

    /**
     * 根据消息类型发送响应消息
     * @param messageType 消息类型枚举
     * @param typeID 群ID或频道ID
     * @param userOpenid 用户OpenID
     * @param content 回复内容
     * @param contentId 引用的消息ID
     */
    private void sendResponseByType(MessageType messageType, String typeID, String userOpenid,
                                    String content, String contentId) {
        switch (messageType) {
            case PRIVATE:
                // 发送私聊消息
                qqBotUtil.sendPrivateMessage(userOpenid, content, contentId);
                break;
            case GROUP:
                // 发送群聊消息
                qqBotUtil.sendGroupMessage(typeID, content, contentId);
                break;
            case CHANNEL:
                // 发送频道消息
                qqBotUtil.sendChannelGroupMessage(typeID, content, contentId);
                break;
            case DIRECT:
                // 发送频道私信
                qqBotUtil.sendChannelPrivateMessage(typeID, content, contentId);
                break;
        }
    }

    /**
     * 消息类型枚举
     * 定义四种QQ消息类型，用于区分不同场景
     */
    private enum MessageType {
        PRIVATE,    // 私聊消息
        GROUP,      // 群聊消息
        CHANNEL,    // 频道消息
        DIRECT      // 频道私信消息
    }
}